#! /usr/bin/env python   
# -*- coding: utf-8 -*-
# 
from flask import g, render_template, flash, redirect, url_for, session, jsonify
import re
import time
import hashlib

# 书籍相关页面
class Book:

    @staticmethod
    def home():
        books = g.db.select('book', {}, 'id DESC')

        return render_template('home.html', books=books)

    @staticmethod
    def index(id):
        book = g.db.find('book', {'id': id})
        chapters = g.db.select('chapter', {'book_id':id}, 'page ASC')

        # comments
        sql = 'SELECT uc.*,en_title,title,star_count,realname,email FROM user_comment uc \
            LEFT JOIN book b ON b.id=uc.book_id \
            LEFT JOIN user u ON u.id=uc.user_id \
            WHERE uc.book_id=%s \
            ORDER BY uc.addtime DESC \
        '
        params = (id,)
        comments = g.db.query(sql, params)
        replys = {}

        for comment in comments:
            if comment['post_comment_id']>0:
                replys[comment['id']] = comment

        # read history
        try:
            account = Account()
            account.create_read_history(id)
            user_star = account.get_favorite(id)
        except Exception as e:
            user_star = None
            print 'Book.index.Error', e

        return render_template('book.html', book=book, entries=chapters, comments=comments, replys=replys, user_star=user_star)

    @staticmethod
    def classify(type):
        books = g.db.select('book', {'classify':type}, 'id DESC')

        return render_template('classify.html', books=books, type=type)

    @staticmethod
    def chapter(book_id, chapter_id):
        book = g.db.find('book', {'id': book_id})
        chapter = g.db.find('chapter', {'id': chapter_id})
        contents = g.db.select('content', {'book_id':book_id, "chapter_id":chapter_id}, 'book_page ASC')

        # description
        description = []
        for x in contents[0:2]:
            description.append(x['en_text'])

        # Next Chapter
        chapter_next = g.db.find('chapter', {'book_id':book_id, 'id': ('>',chapter_id)}, 'page ASC')
        chapter_previous = g.db.find('chapter', {'book_id':book_id, 'id': ('<',chapter_id)}, 'page DESC')

        # read history
        try:
            account = Account()
            account.create_read_history(book_id, chapter_id)
        except Exception as e:
            print 'Book.chapter.Error', e

        return render_template('book_chapter.html', \
            book=book, chapter=chapter, contents=contents, \
            chapter_next=chapter_next, chapter_previous=chapter_previous, description=description)

# 注册登录相关操作
class User:

    @staticmethod
    def add_user(data):
        data['password'] = User.create_md5(data['password'])
        return g.db.add('user', data)

    @staticmethod
    def create_md5(value):
        mhash = hashlib.md5()
        mhash.update(value)
        return mhash.hexdigest()

    @staticmethod
    def validateEmail(email):
        if len(email) > 7:
            if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", email) != None:
                return True

        return False

    @staticmethod
    def do_register(request):
        error = {}
        if request.form['email']=='':
            error['email'] = 'email required'
            flash(error['email'], 'error')
        elif not User.validateEmail(request.form['email']):
            error['email'] = 'email invalid'
            flash(error['email'], 'error')
        elif request.form['password']=='':
            error['password'] = 'password required'
            flash(error['password'], 'error')
        elif request.form['password2']=='':
            error['password2'] = 'password confirm required'
            flash(error['password2'], 'error')
        elif request.form['password'] != request.form['password2']:
            error['password2'] = 'password confirm failed'
            flash(error['password2'], 'error')
        else:
            user_id = User.add_user({'email': request.form['email'], 'password': request.form['password'], \
                'gender': request.form['gender'], 'country': request.form['country'], \
                'realname': request.form['realname'], 'addtime': time.time() \
            })
            if not user_id:
                error['email'] = 'The email `%s` has existed' % (request.form['email'])
                flash(error['email'], 'error')
                return render_template('register.html', error=error, uform=request.form)
            else:
                flash('You were successfully registered.')
                return redirect(url_for('login', user_id=user_id))

        return render_template('register.html', error=error, uform=request.form)

    @staticmethod
    def do_login(request):
        user = g.db.find('user', {'email': request.form['email']})
        if user:
            password = User.create_md5(request.form['password'])
            if password==user['password']:
                logintime = time.time()
                loginip = request.remote_addr
                g.db.save('user', {'id':user['id']}, {'logintime':logintime, 'loginip':loginip})
                user['logintime'] = logintime
                user['loginip'] = loginip
                session['user'] = user
                g.user = session['user']

                flash('You were successfully logined.')
                return redirect(url_for('account'))
            else:
                flash('password is incorrect', 'error')
        else:
            flash('email `%s` not found' % request.form['email'], 'error')

        return render_template('login.html', uform=request.form)

# 登录账户相关操作
class Account:
    def __init__(self):
        if g.user is None:
            raise Exception('please login first')

    def create_read_history(self, book_id, chapter_id=0):
        history = g.db.find('user_history', {'user_id':g.user['id'], 'book_id':book_id})
        if not history:
            g.db.add('user_history', {'user_id':g.user['id'], 'book_id':book_id, \
                'chapter_id':chapter_id, 'addtime':time.time(), 'update_time':time.time()})
        elif chapter_id>0 and chapter_id!=history['chapter_id']:
            g.db.save('user_history', {'id':history['id']}, {'chapter_id':chapter_id, 'update_time':time.time()})

    def index(self, request):
        favorites = g.db.count('user_favorite', {'user_id':g.user['id']})

        #last read
        sql = 'SELECT uh.*,en_title,en_name,title FROM user_history uh \
            LEFT JOIN book b ON b.id=uh.book_id \
            LEFT JOIN chapter c ON c.id=uh.chapter_id \
            WHERE uh.user_id=%s \
            ORDER BY uh.update_time DESC LIMIT 1 \
        '
        last_read = g.db.query(sql, (g.user['id'],))
        last_read = {} if len(last_read)==0 else last_read[0]

        #last comment
        sql = 'SELECT uc.*,en_title,title,star_count FROM user_comment uc \
            LEFT JOIN book b ON b.id=uc.book_id \
            WHERE uc.user_id=%s \
            ORDER BY uc.addtime DESC LIMIT 1 \
        '
        last_comment = g.db.query(sql, (g.user['id'],))
        last_comment = {} if len(last_comment)==0 else last_comment[0]
        
        return render_template('account_index.html', \
            favorites=favorites, last_read=last_read, last_comment=last_comment)

    def change_password(self, request):
        error = {}
        realname = g.user['realname']
        old_password = User.create_md5(request.form['old_password'])
        if old_password!=g.user['password']:
            error['old_password'] = True
            flash('old password is incorrect', 'error')
        elif request.form['password']=='' or request.form['password2']=='':
            error['password'] = True
            flash('password required', 'error')
        elif request.form['password']!=request.form['password2']:
            error['password2'] = True
            flash('password confirm failed', 'error')
        else:
            g.db.save('user', {'id':g.user['id']}, {'realname':request.form['realname'], \
                'password':User.create_md5(request.form['password']), 'update_time':time.time()})

            user = g.db.find('user', {'id': g.user['id']})
            session['user'] = user
            g.user = session['user']
            request.form = None
            flash('password has changed')

        return render_template('account_change_password.html', error=error, realname=realname)

    def get_favorite(self, book_id):
        return g.db.find('user_favorite', {'user_id':g.user['id'], 'book_id':book_id})

    def do_favorite(self, request):
        book_id = request.form['book_id']
        star = g.db.find('user_favorite', {'user_id':g.user['id'], 'book_id':book_id})
        if not star:
            g.db.add('user_favorite', {'user_id':g.user['id'], 'book_id':book_id, 'addtime':time.time()})
            g.db.incr('book', {'id':book_id}, ('star_count',))
            hasStar = True
        else:
            g.db.delete('user_favorite', {'user_id':g.user['id'], 'book_id':book_id});
            g.db.desc('book', {'id':book_id}, ('star_count',))
            hasStar = False

        book = g.db.find('book', {'id':book_id})

        return jsonify(book_id=book_id, star=hasStar, star_count=book['star_count'])

    def favorite(self, request):
        sql = 'SELECT uf.*,en_title,title,star_count FROM user_favorite uf \
            LEFT JOIN book b ON b.id=uf.book_id \
            WHERE uf.user_id=%s \
            ORDER BY uf.addtime DESC \
        '
        params = (g.user['id'],)
        data = g.db.query(sql, params)

        return render_template('account_favorite.html', data=data)

    def read_history(self, request):
        sql = 'SELECT uh.*,en_title,en_name,title FROM user_history uh \
            LEFT JOIN book b ON b.id=uh.book_id \
            LEFT JOIN chapter c ON c.id=uh.chapter_id \
            WHERE uh.user_id=%s \
            ORDER BY uh.update_time DESC \
        '
        params = (g.user['id'],)
        data = g.db.query(sql, params)

        return render_template('account_read_history.html', data=data)

    def add_comment(self, request):
        book_id = request.form['book_id']
        content = request.form['content']
        post_comment_id = request.form['post_comment_id']
        url = request.environ.get('HTTP_REFERER', '/')

        if book_id=='' or not book_id.isdigit() or content=='' or len(content) < 10:
            return redirect(url)
        else:
            flash('comment created')
            comment_id = g.db.add('user_comment', {'user_id':g.user['id'], 'book_id':book_id, \
                'content':content, 'post_comment_id':post_comment_id, 'addtime':time.time()})
            return redirect(url)

    def my_comments(self, request):
        sql = 'SELECT uc.*,en_title,title,star_count FROM user_comment uc \
            LEFT JOIN book b ON b.id=uc.book_id \
            WHERE uc.user_id=%s \
            ORDER BY uc.addtime DESC \
        '
        params = (g.user['id'],)
        data = g.db.query(sql, params)

        return render_template('account_my_comments.html', data=data)

        
